/*
 * @Author: 生俊甫 1758142861@qq.com
 * @Date: 2024-06-08 14:12:28
 * @LastEditors: 生俊甫 1758142861@qq.com
 * @LastEditTime: 2024-06-19 16:00:42
 * @FilePath: /sjf/2024-project/2024_centos/source/user.hpp
 * @Description: 在线用户管理模块：主要实现的是对在线用户长连接的一个管理,包括大厅用户和房间内用户
 */
#pragma once

#include <iostream>
#include <string>
#include <mutex>
#include <unordered_map>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>
#include "./util.hpp"
#include "./log/logger.hpp"

typedef websocketpp::server<websocketpp::config::asio> wsserver_t;

class online_user
{
public:
    /**
     * 用户进入游戏大厅后websocket连接建立时才会加入游戏大厅
     * id:用户id
     * conn: 用户连接信息
     */
    void get_game_hall(uint64_t uid,wsserver_t::connection_ptr& conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _hall_user.insert(std::make_pair(uid,conn));
    }
    /**
     * 用户退出游戏大厅
     * id:用户id
     */
    void exit_game_hall(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _hall_user.erase(uid);
    }
    /**
     * 用户进入游戏房间
     * id:用户id
     * conn: 用户连接信息
     */
    void get_game_room(uint64_t uid,wsserver_t::connection_ptr& conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _room_user.insert(std::make_pair(uid,conn));
    }
    /**
     * 用户退出游戏房间
     * id:用户id
     */
    void exit_game_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _room_user.erase(uid);
    }
    /**
     * 用户进入观战大厅
     * id:用户id
     * conn: 用户连接信息
     */
    void get_watch_room(uint64_t uid,wsserver_t::connection_ptr& conn)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _watch_user.insert(std::make_pair(uid,conn));
    }
    /**
     * 用户退出观战大厅
     * id:用户id
     */
    void exit_watch_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _watch_user.erase(uid);
    }
    /**
     * 判断用户是否在游戏大厅
     * id:用户id
     */
    bool user_in_hall(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        if(_hall_user.find(uid) == _hall_user.end())
            return false;
        return true;
    }
    /**
     * 判断用户是否在游戏房间
     * id:用户id
     */
    bool user_in_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        if(_room_user.find(uid) == _room_user.end())
            return false;
        return true;
    }
    /**
     * 判断用户是否在观战大厅
     * id:用户id
     */
    bool user_in_watch_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        if(_watch_user.find(uid) == _watch_user.end())
            return false;
        return true;
    }
    /**
     * 从游戏大厅获取指定用户的连接信息
     * id:用户id
     */
    wsserver_t::connection_ptr get_conn_in_hall(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _hall_user.find(uid);
        if(it == _hall_user.end())
            return wsserver_t::connection_ptr();
        return it->second;
    }
    /**
     * 从游戏房间获取指定用户的连接信息
     * id:用户id
     */
    wsserver_t::connection_ptr get_conn_in_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _room_user.find(uid);
        if(it == _room_user.end())
            return wsserver_t::connection_ptr();
        return it->second;
    }
    /**
     * 从观战大厅获取指定用户的连接信息
     * id:用户id
     */
    wsserver_t::connection_ptr get_conn_in_watch_room(uint64_t uid)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _watch_user.find(uid);
        if(it == _watch_user.end())
            return wsserver_t::connection_ptr();
        return it->second;
    }
private:
    std::mutex _mutex;
    //大厅用户
    std::unordered_map<uint64_t,wsserver_t::connection_ptr> _hall_user;
    //房间用户
    std::unordered_map<uint64_t,wsserver_t::connection_ptr> _room_user;
    //观战大厅用户
    std::unordered_map<uint64_t,wsserver_t::connection_ptr> _watch_user;
};